# Code/Master/run_all1.R 
# Install dependencies first


# ── 0) Anchor project root (portable, RStudio-independent) ────────────
safely_require <- function(pkg) if (!requireNamespace(pkg, quietly = TRUE)) install.packages(pkg, quiet = TRUE)
safely_require("here")

# PLEASE CHANGE THE DIRECTORY PATH BELOW from "C:/Replication_SAF_Labor" to yours
base_dir <- Sys.getenv("PROJECT_DIR", unset = "C:/WBG/github/490v2/Replication_SAF_Labor/Reproducibility package")
if (!dir.exists(base_dir)) stop("PROJECT_DIR/base_dir does not exist: ", base_dir)

set.seed(12345)


# Create a .here marker once if missing 
.here_path <- file.path(base_dir, ".here")
if (!file.exists(.here_path)) file.create(.here_path)

# Put R at the repo root, then pin {here}
setwd(base_dir)
try(here::i_am("Code/Master/run_all1.R"), silent = TRUE)

root <- normalizePath(here::here(), winslash = "/", mustWork = TRUE)
setwd(root)
Sys.setenv(PROJECT_DIR = root)
options(project.dir = root)

message("Project root: ", root)

# ── 0.1) Pretty duration helper ───────────────────────────────────────
fmt_secs <- function(s) {
  s <- as.numeric(s)
  if (s < 60) return(sprintf("%.1fs", s))
  m <- floor(s / 60); rem <- s - 60*m
  if (m < 60) return(sprintf("%dm %.1fs", m, rem))
  h <- floor(m / 60); m <- m - 60*h
  sprintf("%dh %dm %.1fs", h, m, rem)
}

# ── 1) Helpers ────────────────────────────────────────────────────────
list_rs <- function(rel_dir) {
  d <- file.path(root, rel_dir)
  if (!dir.exists(d)) { message("Missing directory: ", d); return(character()) }
  files <- sort(list.files(d, pattern = "\\.[Rr]$", full.names = TRUE))
  if (!length(files)) message("ℹ️  No .R files in: ", d)
  files
}

# Global timings accumulator
.timings <- list()  # list of list(phase, file, secs)

run <- function(files, label) {
  if (!length(files)) { message("No scripts in ", label); return(invisible()) }
  message("\n▶ ", label, " (", length(files), " scripts)")
  phase_t0 <- Sys.time()
  for (f in files) {
    message("  → ", basename(f))
    env <- new.env(parent = globalenv())     # isolate each script
    t0 <- Sys.time()
    sys.source(f, envir = env)
    elapsed <- as.numeric(difftime(Sys.time(), t0, units = "secs"))
    .timings[[length(.timings) + 1]] <<- list(phase = label, file = basename(f), secs = elapsed)
    message(sprintf("     %s", fmt_secs(elapsed)))
    invisible(gc())
  }
  phase_elapsed <- as.numeric(difftime(Sys.time(), phase_t0, units = "secs"))
 
}

# ── 2) Execute phases ─────────────────────────────────────────────────
all_t0 <- Sys.time()

run(list_rs("Code/00_Inputs"),    "00_Inputs")
run(list_rs("Code/02_Section_2"), "02_Section_2")
run(list_rs("Code/03_Section_3"), "03_Section_3")   

all_elapsed <- as.numeric(difftime(Sys.time(), all_t0, units = "secs"))

# ── 3) Summary ────────────────────────────────────────────────────────
message("\n===== RUNTIME SUMMARY =====")
if (length(.timings)) {
  phases <- split(.timings, vapply(.timings, function(x) x$phase, ""))
  for (ph in names(phases)) {
    total_s <- sum(vapply(phases[[ph]], function(x) x$secs, numeric(1)))
    message(sprintf("%-16s  %s", paste0(ph, ":"), fmt_secs(total_s)))
    # Top 3 slowest scripts in this phase
    ord <- order(vapply(phases[[ph]], function(x) x$secs, 0), decreasing = TRUE)
    top <- phases[[ph]][ord][seq_len(min(3, length(ord)))]
    for (t in top) message(sprintf("   • %-40s %s", t$file, fmt_secs(t$secs)))
  }
}
message(sprintf("\nTOTAL: %s\n", fmt_secs(all_elapsed)))


